package com.aruba.attendance.ui.widget.datepicker

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.aruba.attendance.R
import com.aruba.attendance.ui.widget.calendar.MonthEnum
import kotlinx.coroutines.launch
import java.util.*

/**
 * Created by aruba on 2023/3/9.
 */
@Composable
fun DatePickerDialog(
    showDatePickerDialog: MutableState<Boolean>,
    startYear: Int = 2020,
    selectCallback: ((date: Date) -> Unit)? = null
) {
    if (!showDatePickerDialog.value) return

    val calendar = Calendar.getInstance()
    val years = remember {
        ArrayList<String>().apply {
            for (i in 0..10) {
                if (calendar.get(Calendar.YEAR) - i >= startYear) {
                    add("${calendar.get(Calendar.YEAR) - i}年")
                } else {
                    break
                }
            }
        }
    }
    val targetYearIndex = remember { mutableStateOf(0) }
    val months = remember {
        mutableStateOf(buildMonths(true))
    }
    val targetMonthIndex = remember { mutableStateOf(calendar.get(Calendar.MONTH)) }
    val days = remember {
        mutableStateOf(buildDays(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)))
    }
    val targetDayIndex = remember { mutableStateOf(calendar.get(Calendar.DAY_OF_MONTH) - 1) }
    val scope = rememberCoroutineScope()
    val monthListState = rememberSelectDateState()
    val dayListState = rememberSelectDateState()

    Dialog(onDismissRequest = { showDatePickerDialog.value = false }) {
        Card {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 30.dp, top = 40.dp, end = 30.dp, bottom = 20.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {

                DatePicker(
                    years = years,
                    months = months.value,
                    days = days.value,
                    targetYearIndex = targetYearIndex,
                    targetMonthIndex = targetMonthIndex,
                    targetDayIndex = targetDayIndex,
                    monthListState = monthListState,
                    dayListState = dayListState
                ) { selectYearIndex, selectMonthIndex ->
                    // 日期-月重构
                    val scrollMonth = {
                        scope.launch {
                            if (targetMonthIndex.value >= months.value.size) {
                                targetMonthIndex.value = months.value.size - 1
                            }

                            monthListState.noAnimeScrollToIndex(
                                targetMonthIndex.value,
                                months.value.size
                            )
                        }
                    }
                    if (selectYearIndex == 0 && months.value.size != (calendar.get(Calendar.MONTH) + 1)) {
                        months.value = buildMonths(true)
                        scrollMonth()
                    } else if (selectYearIndex != 0 && months.value.size != 12) {
                        months.value = buildMonths(false)
                        scrollMonth()
                    }

                    // 日期-天重构
                    days.value = buildDays(
                        years[selectYearIndex].substring(0, 4).toInt(),
                        selectMonthIndex
                    ).apply {
                        scope.launch {
                            if (targetDayIndex.value >= size) {
                                targetDayIndex.value = size - 1
                            }

                            dayListState.noAnimeScrollToIndex(targetDayIndex.value, size)
                        }
                    }

                }

                Button(modifier = Modifier.padding(top = 20.dp), onClick = {
                    showDatePickerDialog.value = false
                    val instance = Calendar.getInstance()
                    instance.set(
                        years[targetYearIndex.value].substring(0, 4).toInt(),
                        targetMonthIndex.value,
                        targetDayIndex.value + 1
                    )
                    selectCallback?.invoke(instance.time)
                }) {
                    Text(stringResource(id = R.string.sure))
                }
            }
        }
    }
}

private fun buildMonths(isCurrentYear: Boolean): ArrayList<String> {
    return ArrayList<String>().apply {
        var end = 12
        if (isCurrentYear) {
            val calendar = Calendar.getInstance()
            end = (calendar.get(Calendar.MONTH) + 1)
        }
        for (i in 1..end) {
            add("${if (i < 10) "0$i" else i}月")
        }
    }
}

private fun buildDays(year: Int, month: Int): ArrayList<String> {
    return ArrayList<String>().apply {
        val calendar = Calendar.getInstance()

        var length = MonthEnum.of(month + 1)
            .length(MonthEnum.isLeapYear(year))
        var index = 1
        val isCurrentMonth =
            year == calendar.get(Calendar.YEAR) && month == calendar.get(Calendar.MONTH)
        length = if (isCurrentMonth) calendar.get(Calendar.DAY_OF_MONTH) else length

        while (index < length + 1) {
            if (isCurrentMonth && index > calendar.get(Calendar.DAY_OF_MONTH)) {
                break
            }

            add("${if (index < 10) "0$index" else index}号")
            index++
        }
    }
}